home *** CD-ROM | disk | FTP | other *** search
- *********************************************************************************
- * *
- * NullHandler -- Exception handler for taking care of division by zero *
- * *
- * $VER: NullHandler.a 37.1 (12.8.92) -- An exception handler example *
- * *
- * Copyright (C) 1992 Compos Mentis Software Systems -- Jesper Kehlet *
- * *
- *********************************************************************************
-
- include 'exec/execbase.i'
- include 'dos/dos.i'
- include 'lvo/exec_lvo.i'
-
- IDENT equ 'NULL' ; Identifier for checking existence
-
- section NullHandler,code
-
- *********************************************************************************
- * *
- * This is the main stuff -- the handler installation *
- * *
- *********************************************************************************
-
- moveq #RETURN_FAIL,d0 ; FAIL if not V37+
- movea.l (4).w,a6 ; Get ExecBase
- cmpi.w #37,LIB_VERSION(a6) ; We want V37+ for AllocVec
- blt.b NotV37 ; Bail out
-
- suba.l a5,a5 ; VBR is NULL per default
- btst.b #AFB_68010,AttnFlags+1(a6) ; Get MC type
- beq.b Plain68000
-
- lea GetVBR(pc),a5 ; Address of GetVBR
- jsr _LVOSupervisor(a6) ; Get that VBR base
- movea.l d0,a5 ; and save it
-
- Plain68000 movea.l $14(a5),a1 ; Is there a handler already
- cmpi.l #IDENT,2(a1) ; Check for identifier
- beq.b RemoveUs ; Yup, remove us
-
- move.l a1,OrigHandler ; Store original handler address
-
- moveq #HandlerEnd-Handler,d0 ; We want some memory for handler
- moveq #1,d1 ; Clear it for us
- jsr _LVOAllocVec(a6) ; Now, get it!
-
- move.l d0,$14(a5) ; Install vector #5
-
- movea.l d0,a1 ; Destination
- lea Handler(pc),a0 ; Our code
- moveq #HandlerEnd-Handler,d0 ; Length for copying
- jsr _LVOCopyMem(a6) ; Throw us up in allocated memory
-
- moveq #RETURN_OK,d0 ; Return OK
- NotV37 rts ; And get out
-
- RemoveUs move.l 6(a1),$14(a5) ; Restore old pointer
- jsr _LVOFreeVec(a6) ; Free it
- moveq #RETURN_WARN,d0 ; Return WARN when removed
- rts ; And get out
-
- *********************************************************************************
- * *
- * This is for getting address of VBR on 68010+ *
- * The MOVEC.L VBR,D0 instruction is restricted to Supervisor state, so... *
- * *
- *********************************************************************************
-
- GetVBR movec.l vbr,d0 ; Get VBR
- rte ; Return
-
- *********************************************************************************
- * *
- * This is the handler itself, the meat *
- * *
- *********************************************************************************
-
- Handler bra.b RealHandler ; Skip identifier -- it's not code
-
- dc.l IDENT ; Identifier
- OrigHandler dc.l 0 ; Original handler address
-
- RealHandler movem.l d0-d1/a0,-(sp) ; Save a couple of registers
-
- movea.l $e(sp),a0 ; Get address of data
- move.w -2(a0),d0 ; Get numerator
- move.l #$ffff,d1 ; Largest negative number for denominator
- btst #8,d0 ; Is it <0 ?
- beq.b Negative ; Yup, jump...
- move.l #$7fff,d1 ; Use largest positive instead
-
- Negative lsr.w #7,d0 ; Put the denominator
- andi.l #$1c,d0 ; back on the stack
- move.l d1,0(sp,d0.l) ; instead of the zero
-
- movem.l (sp)+,d0-d1/a0 ; Restore registers
- rte ; Back to normal execution
- HandlerEnd
-
- end
-